#pragma once

#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsView>
#include <QMouseEvent>
#include <QImage>
#include <QWheelEvent>
#include <QGraphicsScene>
#include <QGraphicsSceneWheelEvent>
#include <QScrollBar>
#include <QOpenGLWidget>

#include "qt_graphics_shape_circle_rectangle.h"

class QtQGraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT;
public:
    int m_pen_width=1;
    GraphicsShapeRectangleCirce *shapeItem =nullptr;
    int m_shape_type = 0;
    QColor m_color  = Qt::red;
    bool m_bool_filled = false;
    bool m_drawing=false;
    QPolygonF m_qpolygonf;
	QPixmap* m_qpixmap_mask = nullptr;
public:
	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
		Q_UNUSED(option);
		Q_UNUSED(widget);

        painter->drawPixmap(0, 0, this->pixmap());


        if(m_drawing){
            if(m_qpolygonf.size()>0){
                QPainter painter_erase(m_qpixmap_mask);
                QPen pen(m_color, m_pen_width, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
                painter_erase.setPen(pen);
                painter_erase.drawPolyline(m_qpolygonf);
            }
        }
        if(m_qpixmap_mask!=nullptr)
            painter->drawPixmap(0, 0,*m_qpixmap_mask);
    }

    void hoverMoveEvent(QGraphicsSceneHoverEvent* event)override
    {

        QPointF pos = event->pos();
        QColor color = this->pixmap().toImage().pixelColor((int)pos.x(), (int)pos.y());
        QString rgb_string = " b:" + QString::number(color.blue()) + "g:" + QString::number(color.green()) + "r:" + QString::number(color.red());

        QString message = "x:" + QString::number((int)pos.x()) + " y:" + QString::number((int)pos.y()) + rgb_string;
        emit sendMessage(pos,message);
    }

    void receiveMessage(QPointF pos)
    {
        QColor color = this->pixmap().toImage().pixelColor((int)pos.x(), (int)pos.y());
        QString rgb_string = " b:" + QString::number(color.blue()) + "g:" + QString::number(color.green()) + "r:" + QString::number(color.red());

        QString message = "x:" + QString::number((int)pos.x()) + " y:" + QString::number((int)pos.y()) + rgb_string;
        emit sendMessage(pos,message);
    }

    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {

        if(m_shape_type==0)
            return;
        if (event->button() == Qt::LeftButton) {
            m_drawing = true;
            QPointF point = mapToScene(event->pos());


            if(shapeItem==nullptr)
            {

                if(m_shape_type==1)
                {
                    shapeItem= new GraphicsShapeRectangleCirce(point.x(),point.y(),1,1,m_color);
                    shapeItem->m_bool_filled=m_bool_filled;

                    shapeItem->m_shape_type=0;
                    scene()->addItem(shapeItem);
                }
                else if(m_shape_type==2)
                {
                    shapeItem= new GraphicsShapeRectangleCirce(point.x(),point.y(),1,1,m_color);
                    shapeItem->m_bool_filled=m_bool_filled;

                    shapeItem->m_shape_type=0;
                    scene()->addItem(shapeItem);
                }
            }
            if(m_shape_type==3 || m_shape_type == 4)
            {
                m_qpolygonf.clear();
                m_qpolygonf.push_back(point);
                update();
            }
        }

    }

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override {
        if(m_shape_type==0)
            return;
        if (m_drawing) {
            QPointF point = mapToScene(event->pos());
            if(m_shape_type==1 || m_shape_type==2)
            {
                shapeItem->m_points[1] = point.toPoint();
                shapeItem->update();
            }

            if(m_shape_type==3 || m_shape_type == 4)
            {
                m_qpolygonf.push_back(point);
                update();
            }

        }
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override {
        if (event->button() == Qt::LeftButton) {
            m_drawing = false;
            if(m_shape_type==1 || m_shape_type==2)
            {
                if(shapeItem!=nullptr)
                {
                    emit drawRectangleFinish(shapeItem,m_shape_type);
                    shapeItem = nullptr;
                }
                m_shape_type=0;
            }
            if(m_shape_type==3){
                if(m_qpolygonf.size()>0){
                    QPainter painter_erase(m_qpixmap_mask);
                    QPen pen(m_color, m_pen_width, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
                    painter_erase.setPen(pen);
                    painter_erase.drawPolyline(m_qpolygonf);
					m_qpolygonf.clear();
                }
                emit drawEraseFinish();
                m_shape_type=0;
            }
			if (m_shape_type == 4) {
				if (m_qpolygonf.size() > 0) {
					QPainter painter_erase(m_qpixmap_mask);
					painter_erase.setCompositionMode(QPainter::CompositionMode_Clear);
					QPen pen(Qt::transparent, m_pen_width, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
					painter_erase.setPen(pen);
					painter_erase.drawPolyline(m_qpolygonf);
					m_qpolygonf.clear();
				}
				emit drawEraseFinish();
				m_shape_type = 0;
			}
        }
    }

    void setPenWidth(int width)
    {
        m_pen_width = width;
    }

	void setShapeType(int value)
	{
		m_shape_type = value;
	}
	void setColor(QColor value)
	{
		m_color = value;
	}
	void setFilled(bool value)
	{
		m_bool_filled = value;
	}
    void initMask(QSize size){
        if(m_qpixmap_mask==nullptr){
            m_qpixmap_mask = new QPixmap(size);
            m_qpixmap_mask->fill(Qt::transparent);
			update();
            return;
        }
        if(m_qpixmap_mask->width() != this->pixmap().width() || m_qpixmap_mask->height() != this->pixmap().height()){
            delete m_qpixmap_mask;
            m_qpixmap_mask = new QPixmap(size);
            m_qpixmap_mask->fill(Qt::transparent);
			update();
            return;
        }
    }

    void clearMask()
    {
        if(m_qpixmap_mask!=nullptr)
            m_qpixmap_mask->fill(Qt::transparent);
        update();
    }

    void setMask(QImage image)
    {
		QPixmap pixmap = QPixmap::fromImage(image);
		m_qpixmap_mask = new QPixmap(pixmap);
        update();
    }

signals:
    void sendMessage(QPointF pos,QString message);

    void drawRectangleFinish(QGraphicsItem* p,int draw_type);

    void drawEraseFinish();
};
